Amazon Bedrockでテキスト&画像生成してみた[with Node.js]
育休を4ヶ月取っていた吉川@広島です。9月に復帰しました。
Amazon Bedrock が一般利用可能に – 基盤モデルを利用した生成系 AI アプリケーションの構築とスケール | Amazon Web Services ブログ
GAされたAmazon BedrockをAWS SDK for JS v3+TypeScriptから使ってみました。
環境
- node 20.5.1
- typescript 5.2.2
- @aws-sdk/client-bedrock-runtime 3.422.1
- esbuild 0.19.4
- esbuild-register" 3.5.0
AI21 Labs
早速ですが、まずAI21 Labsを試してみます。こちらはイスラエルのAI企業みたいです。テキスト生成ができるようなので言葉を投げてみます。
コード
// main.ts import { BedrockRuntime } from "@aws-sdk/client-bedrock-runtime"; const client = new BedrockRuntime({ region: "us-east-1" }); const main = async () => { const res = await client.invokeModel({ // Model IDsを参照 https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html modelId: "ai21.j2-ultra-v1", body: JSON.stringify({ prompt: "Knock, knock!", maxTokens: 200, temperature: 0.7, topP: 1, }), accept: "application/json", contentType: "application/json", }); const body = JSON.parse(Buffer.from(res.body).toString("utf-8")); console.log(body.completions[0].data.text.trim()); }; main();
const res = await client.invokeModel({ // Model IDsを参照 https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html modelId: "ai21.j2-ultra-v1", body: JSON.stringify({ prompt: "Knock, knock!", maxTokens: 200, temperature: 0.7, topP: 1, }), accept: "application/json", contentType: "application/json", });
v2互換スタイルで書いてみました(v3スタイルはバンドルサイズの優位性があるんでしょうが、どうしてもこっちを使う癖が抜けず)。v3スタイルの場合は
import { BedrockRuntimeClient, InvokeModelCommand } from "@aws-sdk/client-bedrock-runtime"; const client = new BedrockRuntimeClient({ region: "us-east-1" }); const main = async () => { const res = await client.send(new InvokeModelCommand({/* 省略... */})) // 省略...
のようになるでしょう。
実行
esbuild-registerでビルド+実行します。
node -r esbuild-register main.ts # 以下出力: # Who's there? # Boo # Boo who? # Don't cry, it's just a joke!
Stability AI
続いてStability AIを試してみます。こちらは画像生成ができます。
コード
// main.ts import { BedrockRuntime } from "@aws-sdk/client-bedrock-runtime"; import { writeFileSync } from "fs"; const client = new BedrockRuntime({ region: "us-east-1" }); const main = async () => { const res = await client.invokeModel({ // Model IDsを参照 https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html modelId: "stability.stable-diffusion-xl-v0", body: JSON.stringify({ text_prompts: [ { // プロンプト text: "crazy mad gorilla", }, ], cfg_scale: 10, seed: 20, steps: 50, }), accept: "application/json", contentType: "application/json", }); const body = JSON.parse(Buffer.from(res.body).toString("utf-8")); if (body.result !== "success") { throw new Error("Failed to invoke model"); } writeFileSync("./out.png", body.artifacts[0].base64, { encoding: "base64" }); };
実行
同じように実行します。
node -r esbuild-register main.ts
./out.png
に画像が出力されます。
今回はこんな出力でした。
なかなかイケてますね(?)
感想
ということで楽しく遊べそうな雰囲気でした。AWSアカウントが1つあれば色々な会社のAI製品のAPIを叩けるのが良いですね。
少し気になったのは、SDKなのに .invokeModel()
に渡す引数がfetch APIやAxiosを使う場合と同じ程度の型安全性しかないように見える点です。accept
や contentType
まで指定するので通信処理を隠蔽できていない感があります。
これはおそらく使いたいAI製品によって入出力のフォーマットが全く違うからだと思いますが、ユニオンやジェネリクスを活用したり、使うAIによってメソッドを変えるなどで型付けできそうな気はします。このあたりをより良くするために @aws-sdk/client-bedrock-runtime
をラップするOSSとか作ってみると面白いかもしれませんね。もしくは公式からラッパーが出るかも?
以上、参考になれば幸いです。